import 'package:ble_measure_plugin/utils/ext.dart';
import 'package:flutter_blue/flutter_blue.dart';

import '../ble_measure_plugin.dart';

abstract class BaseDeviceModel {
  void connect(BluetoothDevice device);

  EventHandlerMap<BluetoothDeviceState>? deviceStateHandler;

  void addDeviceStateListener(
      EventHandlerMap<BluetoothDeviceState>? deviceStateHandler) {
    this.deviceStateHandler = deviceStateHandler;
  }

  void release(){
    this.deviceStateHandler = null;
  }
}

abstract class BaseDeviceMeasureModel extends BaseDeviceModel {

  String get serviceUuid => "";
  String get characteristicWriteable => "";
  String get characteristicReadable => "";

  var hasConnect = false;
  var hasMeasure = false;

  BluetoothDevice? measureDevice;
  BluetoothCharacteristic? _readCharacteristic;
  BluetoothCharacteristic? _writeCharacteristic;
  BluetoothDeviceState? _deviceState = BluetoothDeviceState.disconnected;

  var hasListener = false;


  @override
  void connect(BluetoothDevice device) {
    if (hasConnect) {
      return;
    }
    measureDevice = device;
    var inConnectProcess = false;
    measureDevice?.state.listen((event) async {

      if (event != BluetoothDeviceState.connected &&
          event != BluetoothDeviceState.connecting) {
        print("开始连接======>${event}");
        inConnectProcess = true;
        hasConnect = true;
        await measureDevice?.connect();
        BleMeasurePlugin.instance.linkDevices.add(device);
        inConnectProcess = false;
      } else {
        hasConnect = false;
        BleMeasurePlugin.instance.linkDevices.remove(device);
        inConnectProcess = false;
        hasMeasure = false;
        // _readCharacteristic.value
      }
      if (measureDevice != null) {
        if (event == BluetoothDeviceState.connected) {
          var discoverServices = await device.discoverServices();
          var inProcess = false;
          for (var service in discoverServices) {
            if(inProcess){
              return;
            }
            if (service.uuid.toString() == serviceUuid) {

              for (var element in service.characteristics) {
                print("====>${element.uuid.toString()}");
                var chaUuid = element.uuid.toString();
                if (chaUuid == characteristicWriteable) {
                  _writeCharacteristic = element;
                }
                if (chaUuid == characteristicReadable) {
                  _readCharacteristic = element;
                  if(_readCharacteristic?.isNotifying==false){
                    try {
                      await _readCharacteristic?.setNotifyValue(true);
                      onOpenSuccess();
                      print("开启成功.....");
                    } catch (e) {
                      print("开启失败.....");
                    }
                  }
                  if(!hasListener){
                    _readCharacteristic?.value.listen((event) {
                      hasListener = true;
                      var va16 = event.map((e) {
                        var data = e.toRadixString(16).toUpperCase();
                        if (data.length == 1) {
                          data = "0$data";
                        }
                        return data;
                      }).toList();
                      if (va16.isNotEmpty) {
                        onReceiveData(va16);
                      }
                    });
                  }
                  break;
                }
              }
            }
          }
        } else if (event == BluetoothDeviceState.disconnected) {
          BleMeasurePlugin.instance.linkDevices.remove(device);
        }
        if (deviceStateHandler != null && _deviceState != event) {
          _deviceState = event;
          deviceStateHandler!(event);
        }
      }
    });
  }

  void onReceiveData(List<String> data);

  void disconnect() {
    BleMeasurePlugin.instance.linkDevices.remove(measureDevice);
    measureDevice?.disconnect();
    release();
  }




  BaseDeviceMeasureModel(){
    init();
  }

  void init(){

  }

  void onOpenSuccess(){

  }

  @override
  void release() {
    hasConnect = false;
    hasListener = false;
    _deviceState = BluetoothDeviceState.disconnected;
    measureDevice = null;
    _readCharacteristic = null;
    _writeCharacteristic = null;
    super.release();
  }
}
